package com.school.sports.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.school.sports.entity.SysDictData;
import com.school.sports.service.SysDictDataService;
import com.school.sports.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 字典数据管理控制器
 * 提供字典数据的CRUD操作、缓存刷新等功能
 */
@RestController
@RequestMapping("/api/dict-data")
public class SysDictDataController {

    private static final Logger logger = LoggerFactory.getLogger(SysDictDataController.class);

    @Autowired
    private SysDictDataService sysDictDataService;

    /**
     * 分页查询字典数据列表
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param sysDictData 查询条件
     * @return 分页结果
     */
    @GetMapping("/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasRole('管理员')")
    public Result<IPage<SysDictData>> getDictDataPage(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            SysDictData sysDictData) {

        logger.info("分页查询字典数据列表，当前页码：{}，每页条数：{}，查询条件：{}", currentPage, pageSize, sysDictData);

        // 参数校验
        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<SysDictData> page = sysDictDataService.getDictDataPage(currentPage, pageSize, sysDictData);
            logger.info("查询字典数据列表成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询字典数据列表异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID查询字典数据详情
     * @param dictDataId 字典数据ID
     * @return 字典数据详情
     */
    @GetMapping("/{dictDataId}")
    @PreAuthorize("hasRole('管理员')")
    public Result<SysDictData> getDictDataById(@PathVariable("dictDataId") Long dictDataId) {
        logger.info("查询字典数据详情，字典数据ID：{}", dictDataId);

        if (dictDataId == null || dictDataId <= 0) {
            return Result.fail("字典数据ID无效");
        }

        try {
            SysDictData dictData = sysDictDataService.getById(dictDataId);
            if (dictData == null) {
                return Result.fail("字典数据不存在");
            }
            logger.info("查询字典数据详情成功，字典标签：{}", dictData.getDictLabel());
            return Result.success(dictData);
        } catch (Exception e) {
            logger.error("查询字典数据详情异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据字典类型ID查询字典数据列表
     * @param dictTypeId 字典类型ID
     * @return 字典数据列表
     */
    @GetMapping("/type-id/{dictTypeId}")
    @PreAuthorize("hasAnyRole('管理员', '老师', '学生', '裁判')")
    public Result<List<SysDictData>> getDictDataByTypeId(@PathVariable("dictTypeId") Long dictTypeId) {
        logger.info("根据字典类型ID查询字典数据列表，字典类型ID：{}", dictTypeId);

        if (dictTypeId == null || dictTypeId <= 0) {
            return Result.fail("字典类型ID无效");
        }

        try {
            List<SysDictData> dictDataList = sysDictDataService.getDictDataByTypeId(dictTypeId);
            logger.info("根据字典类型ID查询字典数据列表成功，共{}条数据", dictDataList.size());
            return Result.success(dictDataList);
        } catch (Exception e) {
            logger.error("根据字典类型ID查询字典数据列表异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据字典类型编码查询字典数据列表
     * @param dictTypeCode 字典类型编码
     * @return 字典数据列表
     */
    @GetMapping("/type-code/{dictTypeCode}")
    @PreAuthorize("hasAnyRole('管理员', '老师', '学生', '裁判')")
    public Result<List<SysDictData>> getDictDataByTypeCode(@PathVariable("dictTypeCode") String dictTypeCode) {
        logger.info("根据字典类型编码查询字典数据列表，字典类型编码：{}", dictTypeCode);

        if (dictTypeCode == null || dictTypeCode.trim().isEmpty()) {
            return Result.fail("字典类型编码不能为空");
        }

        try {
            List<SysDictData> dictDataList = sysDictDataService.getDictDataByTypeCode(dictTypeCode);
            logger.info("根据字典类型编码查询字典数据列表成功，共{}条数据", dictDataList.size());
            return Result.success(dictDataList);
        } catch (Exception e) {
            logger.error("根据字典类型编码查询字典数据列表异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据字典类型编码和字典值查询字典数据
     * @param dictTypeCode 字典类型编码
     * @param dictValue 字典值
     * @return 字典数据对象
     */
    @GetMapping("/by-value")
    @PreAuthorize("hasAnyRole('管理员', '老师', '学生', '裁判')")
    public Result<SysDictData> getDictDataByTypeCodeAndValue(
            @RequestParam("dictTypeCode") String dictTypeCode,
            @RequestParam("dictValue") String dictValue) {

        logger.info("根据字典类型编码和字典值查询字典数据：{} - {}", dictTypeCode, dictValue);

        if (dictTypeCode == null || dictTypeCode.trim().isEmpty()) {
            return Result.fail("字典类型编码不能为空");
        }
        if (dictValue == null || dictValue.trim().isEmpty()) {
            return Result.fail("字典值不能为空");
        }

        try {
            SysDictData dictData = sysDictDataService.getDictDataByTypeCodeAndValue(dictTypeCode, dictValue);
            if (dictData == null) {
                return Result.fail("字典数据不存在或已停用");
            }
            logger.info("根据字典类型编码和字典值查询字典数据成功");
            return Result.success(dictData);
        } catch (Exception e) {
            logger.error("根据字典类型编码和字典值查询字典数据异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据字典类型编码和字典标签查询字典数据
     * @param dictTypeCode 字典类型编码
     * @param dictLabel 字典标签
     * @return 字典数据对象
     */
    @GetMapping("/by-label")
    @PreAuthorize("hasAnyRole('管理员', '老师', '学生', '裁判')")
    public Result<SysDictData> getDictDataByTypeCodeAndLabel(
            @RequestParam("dictTypeCode") String dictTypeCode,
            @RequestParam("dictLabel") String dictLabel) {

        logger.info("根据字典类型编码和字典标签查询字典数据：{} - {}", dictTypeCode, dictLabel);

        if (dictTypeCode == null || dictTypeCode.trim().isEmpty()) {
            return Result.fail("字典类型编码不能为空");
        }
        if (dictLabel == null || dictLabel.trim().isEmpty()) {
            return Result.fail("字典标签不能为空");
        }

        try {
            SysDictData dictData = sysDictDataService.getDictDataByTypeCodeAndLabel(dictTypeCode, dictLabel);
            if (dictData == null) {
                return Result.fail("字典数据不存在或已停用");
            }
            logger.info("根据字典类型编码和字典标签查询字典数据成功");
            return Result.success(dictData);
        } catch (Exception e) {
            logger.error("根据字典类型编码和字典标签查询字典数据异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取所有启用的字典数据（用于缓存）
     * @return 字典数据映射
     */
    @GetMapping("/all-enabled")
    @PreAuthorize("hasAnyRole('管理员', '老师', '学生', '裁判')")
    public Result<Map<String, List<SysDictData>>> getAllEnabledDictData() {
        logger.info("获取所有启用的字典数据");

        try {
            Map<String, List<SysDictData>> dictDataMap = sysDictDataService.getAllEnabledDictData();
            logger.info("获取所有启用的字典数据成功，共{}个字典类型", dictDataMap.size());
            return Result.success(dictDataMap);
        } catch (Exception e) {
            logger.error("获取所有启用的字典数据异常：{}", e.getMessage(), e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 根据标签模糊查询字典数据
     * @param dictLabel 字典标签
     * @return 字典数据列表
     */
    @GetMapping("/search")
    @PreAuthorize("hasRole('管理员')")
    public Result<List<SysDictData>> getDictDataByLabel(@RequestParam("dictLabel") String dictLabel) {
        logger.info("根据标签模糊查询字典数据：{}", dictLabel);

        if (dictLabel == null || dictLabel.trim().isEmpty()) {
            return Result.fail("字典标签不能为空");
        }

        try {
            List<SysDictData> dictDataList = sysDictDataService.getDictDataByLabel(dictLabel);
            logger.info("根据标签模糊查询字典数据成功，共{}个结果", dictDataList.size());
            return Result.success(dictDataList);
        } catch (Exception e) {
            logger.error("根据标签模糊查询字典数据异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 新增字典数据
     * @param sysDictData 字典数据信息
     * @return 操作结果
     */
    @PostMapping
    @PreAuthorize("hasRole('管理员')")
    public Result<String> addDictData(@Valid @RequestBody SysDictData sysDictData) {
        logger.info("新增字典数据：{}", sysDictData.getDictLabel());

        try {
            // 参数校验
            if (sysDictData.getDictTypeId() == null || sysDictData.getDictTypeId() <= 0) {
                return Result.fail("字典类型ID无效");
            }
            if (sysDictData.getDictLabel() == null || sysDictData.getDictLabel().trim().isEmpty()) {
                return Result.fail("字典标签不能为空");
            }
            if (sysDictData.getDictValue() == null || sysDictData.getDictValue().trim().isEmpty()) {
                return Result.fail("字典值不能为空");
            }

            // 获取当前用户ID
            Long currentUserId = getCurrentUserId();

            boolean success = sysDictDataService.addDictData(sysDictData, currentUserId);
            if (success) {
                logger.info("新增字典数据成功：{}", sysDictData.getDictLabel());
                return Result.success("添加成功");
            } else {
                return Result.fail("添加失败，字典值可能已存在");
            }
        } catch (Exception e) {
            logger.error("新增字典数据异常：{}", e.getMessage(), e);
            return Result.fail("添加失败：" + e.getMessage());
        }
    }

    /**
     * 更新字典数据
     * @param sysDictData 字典数据信息
     * @return 操作结果
     */
    @PutMapping
    @PreAuthorize("hasRole('管理员')")
    public Result<String> updateDictData(@Valid @RequestBody SysDictData sysDictData) {
        logger.info("更新字典数据：{}", sysDictData.getId());

        if (sysDictData.getId() == null || sysDictData.getId() <= 0) {
            return Result.fail("字典数据ID无效");
        }

        try {
            // 获取当前用户ID
            Long currentUserId = getCurrentUserId();

            boolean success = sysDictDataService.updateDictData(sysDictData, currentUserId);
            if (success) {
                logger.info("更新字典数据成功：{}", sysDictData.getId());
                return Result.success("更新成功");
            } else {
                return Result.fail("更新失败，字典数据不存在或字典值已存在");
            }
        } catch (Exception e) {
            logger.error("更新字典数据异常：{}", e.getMessage(), e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }

    /**
     * 删除字典数据
     * @param dictDataId 字典数据ID
     * @return 操作结果
     */
    @DeleteMapping("/{dictDataId}")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> deleteDictData(@PathVariable("dictDataId") Long dictDataId) {
        logger.info("删除字典数据：{}", dictDataId);

        if (dictDataId == null || dictDataId <= 0) {
            return Result.fail("字典数据ID无效");
        }

        try {
            boolean success = sysDictDataService.deleteDictData(dictDataId);
            if (success) {
                logger.info("删除字典数据成功：{}", dictDataId);
                return Result.success("删除成功");
            } else {
                return Result.fail("删除失败，字典数据不存在");
            }
        } catch (Exception e) {
            logger.error("删除字典数据异常：{}", e.getMessage(), e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除字典数据
     * @param dictDataIds 字典数据ID列表
     * @return 操作结果
     */
    @DeleteMapping("/batch")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> batchDeleteDictData(@RequestBody List<Long> dictDataIds) {
        logger.info("批量删除字典数据：{}", dictDataIds);

        if (dictDataIds == null || dictDataIds.isEmpty()) {
            return Result.fail("请选择要删除的字典数据");
        }

        try {
            boolean success = sysDictDataService.batchDeleteDictData(dictDataIds);
            if (success) {
                logger.info("批量删除字典数据成功，共{}个字典数据", dictDataIds.size());
                return Result.success("批量删除成功");
            } else {
                return Result.fail("批量删除失败");
            }
        } catch (Exception e) {
            logger.error("批量删除字典数据异常：{}", e.getMessage(), e);
            return Result.fail("批量删除失败：" + e.getMessage());
        }
    }

    /**
     * 修改字典数据状态
     * @param dictDataId 字典数据ID
     * @param status 状态
     * @return 操作结果
     */
    @PutMapping("/{dictDataId}/status")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> updateDictDataStatus(
            @PathVariable("dictDataId") Long dictDataId,
            @RequestParam("status") Integer status) {

        logger.info("修改字典数据状态：{} -> {}", dictDataId, status);

        if (dictDataId == null || dictDataId <= 0) {
            return Result.fail("字典数据ID无效");
        }

        if (status == null || (status != 0 && status != 1)) {
            return Result.fail("状态值无效");
        }

        try {
            Long currentUserId = getCurrentUserId();
            boolean success = sysDictDataService.updateDictDataStatus(dictDataId, status, currentUserId);
            if (success) {
                logger.info("修改字典数据状态成功：{}", dictDataId);
                return Result.success("状态修改成功");
            } else {
                return Result.fail("状态修改失败");
            }
        } catch (Exception e) {
            logger.error("修改字典数据状态异常：{}", e.getMessage(), e);
            return Result.fail("状态修改失败：" + e.getMessage());
        }
    }

    /**
     * 批量更新字典数据排序
     * @param dictDataMap 字典数据ID和排序值的映射
     * @return 操作结果
     */
    @PutMapping("/sort")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> batchUpdateDictSort(@RequestBody Map<Long, Integer> dictDataMap) {
        logger.info("批量更新字典数据排序，共{}个数据", dictDataMap.size());

        if (dictDataMap == null || dictDataMap.isEmpty()) {
            return Result.fail("请提供要更新的排序数据");
        }

        try {
            Long currentUserId = getCurrentUserId();
            boolean success = sysDictDataService.batchUpdateDictSort(dictDataMap, currentUserId);
            if (success) {
                logger.info("批量更新字典数据排序成功");
                return Result.success("排序更新成功");
            } else {
                return Result.fail("排序更新失败");
            }
        } catch (Exception e) {
            logger.error("批量更新字典数据排序异常：{}", e.getMessage(), e);
            return Result.fail("排序更新失败：" + e.getMessage());
        }
    }

    /**
     * 刷新字典数据缓存
     * @return 操作结果
     */
    @PostMapping("/refresh-cache")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> refreshDictDataCache() {
        logger.info("刷新字典数据缓存");

        try {
            boolean success = sysDictDataService.refreshDictDataCache();
            if (success) {
                logger.info("刷新字典数据缓存成功");
                return Result.success("缓存刷新成功");
            } else {
                return Result.fail("缓存刷新失败");
            }
        } catch (Exception e) {
            logger.error("刷新字典数据缓存异常：{}", e.getMessage(), e);
            return Result.fail("缓存刷新失败：" + e.getMessage());
        }
    }

    /**
     * 检查字典值是否在指定字典类型中存在
     * @param dictTypeId 字典类型ID
     * @param dictValue 字典值
     * @param excludeId 排除的ID
     * @return 检查结果
     */
    @GetMapping("/check-value")
    @PreAuthorize("hasRole('管理员')")
    public Result<Boolean> checkDictValueExists(
            @RequestParam("dictTypeId") Long dictTypeId,
            @RequestParam("dictValue") String dictValue,
            @RequestParam(value = "excludeId", required = false) Long excludeId) {

        logger.info("检查字典值是否存在：{} - {}，排除ID：{}", dictTypeId, dictValue, excludeId);

        if (dictTypeId == null || dictTypeId <= 0) {
            return Result.fail("字典类型ID无效");
        }
        if (dictValue == null || dictValue.trim().isEmpty()) {
            return Result.fail("字典值不能为空");
        }

        try {
            boolean exists = sysDictDataService.checkDictValueExists(dictTypeId, dictValue, excludeId);
            logger.info("检查字典值是否存在完成：{} - {} -> {}", dictTypeId, dictValue, exists);
            return Result.success(exists);
        } catch (Exception e) {
            logger.error("检查字典值是否存在异常：{}", e.getMessage(), e);
            return Result.fail("检查失败：" + e.getMessage());
        }
    }

    /**
     * 获取当前用户ID
     * 这里简化处理，实际应该从Spring Security上下文中获取
     * @return 用户ID
     */
    private Long getCurrentUserId() {
        // TODO: 从Spring Security上下文中获取当前用户ID
        return 1L; // 临时返回固定值
    }
}